package writer;
import gui.ConfirmWindow;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import models.asl.Edge;
import models.asl.Graph;
import models.asl.Node;
import models.asl.NodeType;

public class ASLFileWriter {

    public static void writeASLFile(String fileName, Graph domainGraph) {
        File file = new File(fileName);
        System.out.println("Write to File:" + fileName);
        try {
            if(!file.exists()) {
                file.createNewFile();
            }
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            
            BufferedWriter bw = new BufferedWriter(fw);


            Node triggerNode = domainGraph.findNodeById(-1);
            if(triggerNode != null) {
                DFSOutput(domainGraph, triggerNode, bw);
            }
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void writeASLFile(String fileName, String content) {
        File file = new File(fileName);
        System.out.println("Write to File:" + fileName);
        try {
            if(!file.exists()) {
                file.createNewFile();
            }
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            
            BufferedWriter bw = new BufferedWriter(fw);
            bw.append(content);
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void writeToConfirmWindow(ConfirmWindow confirmWindow, Graph domainGraph) {
//        confirmWindow
        StringBuilder sb = new StringBuilder();
        Node triggerNode = domainGraph.findNodeById(-1);
        if(triggerNode != null) {
            try {
                DFSOutput(domainGraph, triggerNode, sb);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        confirmWindow.getTextArea().setText(sb.toString());
    }
    
    private static void DFSOutput(Graph domainGraph, Node currentNode, BufferedWriter bw) throws IOException {
        if(currentNode.getOutgoingEdges() != null) {
            if(currentNode.getType().equals(NodeType.TRIGGINGEVENT)) {
                bw.write(currentNode.getName() + ".\n" );
            } else if(currentNode.getType().equals(NodeType.CONTEXT_CONDITION)) {
                bw.write(currentNode.getName() + " <- ");
            } else if(currentNode.getType().equals(NodeType.ACTION)) {
                bw.write(currentNode.getName());
                if(currentNode.getOutgoingEdges() == null || currentNode.getOutgoingEdges().isEmpty()) {
                    bw.write(".\n");
                } else {
                    bw.write(";");
                }
            } else if(currentNode.getType().equals(NodeType.PLAN)) {
                bw.write("\n" + currentNode.getName() + " : ");
                
            } else if(currentNode.getType().equals(NodeType.SUBGOAL)) {
                bw.write(currentNode.getName() + ".");
            }

            for(Edge outGoingEdges : currentNode.getOutgoingEdges()) {
                DFSOutput(domainGraph, domainGraph.findNodeById(outGoingEdges.getDestinationId()), bw);
            }
        } else {
            return;
        }
        
    }
    
    private static void DFSOutput(Graph domainGraph, Node currentNode, StringBuilder bw) throws IOException {
        if(currentNode.getOutgoingEdges() != null) {
            if(currentNode.getType().equals(NodeType.TRIGGINGEVENT)) {
                bw.append(currentNode.getName().substring(1) + ".\n" );
            } else if(currentNode.getType().equals(NodeType.CONTEXT_CONDITION)) {
                bw.append(currentNode.getName() + " <- ");
            } else if(currentNode.getType().equals(NodeType.ACTION)) {
                bw.append(currentNode.getName());
                if(currentNode.getOutgoingEdges() == null || currentNode.getOutgoingEdges().isEmpty()) {
                    bw.append(".\n");
                } else {
                    bw.append(";");
                }
            } else if(currentNode.getType().equals(NodeType.PLAN)) {
                bw.append("\n" + currentNode.getName() + " : ");
                
            } else if(currentNode.getType().equals(NodeType.SUBGOAL)) {
                bw.append(currentNode.getName() + ".");
            }

            for(Edge outGoingEdges : currentNode.getOutgoingEdges()) {
                DFSOutput(domainGraph, domainGraph.findNodeById(outGoingEdges.getDestinationId()), bw);
            }
        } else {
            return;
        }
        
    }
}
